//
//  BluetoothCenter.m
//  YiJun
//
//  Created by liangrongchang on 2017/4/20.
//  Copyright © 2017年 Rochang. All rights reserved.
//

#import "BluetoothCenter.h"
#import "SVProgressHUD.h"

/** 指定的服务UUID */
#define ServiceUUID [CBUUID UUIDWithString:@"FF12"]
/** 指定的读取特征UUId */
#define CharacteristicReadUUID [CBUUID UUIDWithString:@"FF02"]
/** 指定的写入特征UUId */
#define CharacteristicWriteUUID [CBUUID UUIDWithString:@"FF01"]
/** 修改名字UUID */
#define CharacteristicNameUUID [CBUUID UUIDWithString:@"FF06"]
/** 修改密码UUID */
#define CharacteristicPwdUUID [CBUUID UUIDWithString:@"FF05"]

typedef NS_ENUM(NSUInteger, CMDType) {
    CMDType86,
    CMDType85
};

@interface BluetoothCenter ()<CBCentralManagerDelegate, CBPeripheralDelegate>

@property (strong, nonatomic) CBCentralManager *centralManager;
@property (strong, nonatomic) NSMutableArray<NSUUID *> *peripheralUUIDs;
@property (nonatomic, strong) CBCharacteristic *writeCharacteristic;
@property (nonatomic, strong) CBCharacteristic *nameCharacteristic;
@property (nonatomic, strong) CBCharacteristic *pwdCharacteristic;
@property (nonatomic, strong) NSMutableArray<CBPeripheral *> *peripherals;

@end

@implementation BluetoothCenter

+ (instancetype)shareInstance {
    static BluetoothCenter *_instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[self alloc] init];
    });
    return _instance;
}

- (instancetype)init {
    if (self = [super init]) {
        self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
        if (![self userGetValueForKey:MaxSpeed]) {
            [self userSetValue:@"6" forKey:MaxSpeed];
        }
        if (![self userGetValueForKey:StrongSet]) {
            [self userSetValue:@"50" forKey:StrongSet];
        }
        if (![self userGetValueForKey:TurnSet]) {
            [self userSetValue:@"50" forKey:TurnSet];
        }
        if (![self userGetValueForKey:TimeSet]) {
            [self userSetValue:@"0" forKey:TimeSet];
        }
        
        if (![self getBluetoothset:CMDType86].length) {
            NSMutableDictionary *set = [[NSMutableDictionary alloc] init];
            [set setObject:@"0c" forKey:@"0"];
            [set setObject:@"32" forKey:@"1"];
            [set setObject:@"32" forKey:@"2"];
            [set setObject:@"00" forKey:@"3"];
            [set setObject:@"00" forKey:@"4"];
            [set setObject:@"00" forKey:@"5"];
            [set setObject:@"00" forKey:@"6"];
            [set setObject:@"00" forKey:@"7"];
            [set setObject:@"00" forKey:@"8"];
            [set setObject:@"00" forKey:@"9"];
            [set setObject:@"00" forKey:@"10"];
            [set setObject:@"00" forKey:@"11"];
            [set setObject:@"00" forKey:@"12"];
            [set setObject:@"00" forKey:@"13"];
            [set setObject:@"86" forKey:@"14"];
            NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
            [user setObject:set forKey:BluetoothSet86];
        }
        
        if (![self getBluetoothset:CMDType85].length) {
            NSMutableDictionary *set = [[NSMutableDictionary alloc] init];
            [set setObject:@"12" forKey:@"0"];
            [set setObject:@"00" forKey:@"1"];
            [set setObject:@"00" forKey:@"2"];
            [set setObject:@"00" forKey:@"3"];
            [set setObject:@"00" forKey:@"4"];
            [set setObject:@"b4" forKey:@"5"];
            [set setObject:@"00" forKey:@"6"];
            [set setObject:@"00" forKey:@"7"];
            [set setObject:@"00" forKey:@"8"];
            [set setObject:@"00" forKey:@"9"];
            [set setObject:@"00" forKey:@"10"];
            [set setObject:@"00" forKey:@"11"];
            [set setObject:@"00" forKey:@"12"];
            [set setObject:@"00" forKey:@"13"];
            [set setObject:@"85" forKey:@"14"];
            NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
            [user setObject:set forKey:BluetoothSet85];
        }
    }
    return self;
}

- (void)scanperipheral {
    if (self.isBluetoothOpen) {
        [self.peripherals removeAllObjects];
        [self.peripheralUUIDs removeAllObjects];
        [self.centralManager scanForPeripheralsWithServices:nil options:nil];
    }
}

- (void)connetPeripheral:(CBPeripheral *)peripheral {
    self.currentPeripheral = peripheral;
    [self.centralManager connectPeripheral:peripheral options:nil];
    [self.centralManager stopScan];
}

- (void)stopScand {
    if (self.centralManager.isScanning) {
        [self.centralManager stopScan];
    }
}

#pragma mark - CBCentralManagerDelegate
/** 状态改变 */
- (void)centralManagerDidUpdateState:(CBCentralManager *)central {
    if (central.state == CBManagerStatePoweredOn) {
        self.isBluetoothOpen = YES;
        // 扫描外设
    } else {
        self.isBluetoothOpen = NO;
        self.currentPeripheral = nil;
        NSLog(@"蓝牙没开启");
    }
    NSString *obj = self.isBluetoothOpen ? @"1" : @"0";
    [[NSNotificationCenter defaultCenter] postNotificationName:BluetoochStatusChange object:obj];
}

/** 扫描到外设 */
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI {
    if (![self.peripheralUUIDs containsObject:peripheral.identifier]) {
        [self.peripheralUUIDs addObject:peripheral.identifier];
        [self.peripherals addObject:peripheral];
        if ([self.delegate respondsToSelector:@selector(bluetoothCenterDidScandPeripheral:)]) {
            [self.delegate bluetoothCenterDidScandPeripheral:peripheral];
        }
    }
}

/** 连接到外设 */
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral {
    self.isConnectPeripheral = YES;
    peripheral.delegate = self;
    [peripheral discoverServices:nil];
    [[NSNotificationCenter defaultCenter] postNotificationName:BluetoochConnectPeripher object:peripheral];
}

/** 断开连接 */
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(nullable NSError *)error{
    self.isConnectPeripheral = NO;
    self.currentPeripheral = nil;
    [self.peripherals removeAllObjects];
    [self.peripheralUUIDs removeAllObjects];
    [[NSNotificationCenter defaultCenter] postNotificationName:BluetoochDisConnectPeripher object:nil];
}


#pragma mark - CBPeripheralDelegate
/** 外围设备发现到服务后 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error {
    for (CBService *service in peripheral.services) {
        if ([service.UUID isEqual:ServiceUUID]) {
            [peripheral discoverCharacteristics:nil forService:service];
        }
    }
}

/** 外围设备发现服务的特征后 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error {
    for (CBCharacteristic *characteristic in service.characteristics) {
        if ([characteristic.UUID isEqual:CharacteristicReadUUID]) {
            // 设置通知,外围设备有数据响应会调用代理方法
            [peripheral setNotifyValue:YES forCharacteristic:characteristic];
        }
        else if ([characteristic.UUID isEqual:CharacteristicWriteUUID]) {
            self.writeCharacteristic = characteristic;
        }
        else if ([characteristic.UUID isEqual:CharacteristicNameUUID]) {
            self.nameCharacteristic = characteristic;
        }
        else if ([characteristic.UUID isEqual:CharacteristicPwdUUID]) {
            self.pwdCharacteristic = characteristic;
        }
    }
}

/** 接收到外围设备的响应数据 */
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    if ([characteristic.UUID isEqual:CharacteristicReadUUID]) {
        NSString *datastr = [NSString stringWithFormat:@"%@", characteristic.value];
        [[NSNotificationCenter defaultCenter] postNotificationName:BluetoochReadData object:datastr];
        [self analysisDataWith:datastr];
    }
}

#pragma mark - read
- (void)analysisDataWith:(NSString *)dataStr {
    NSArray *array = [dataStr componentsSeparatedByString:@" "];
    NSString *str0 = [array objectAtIndex:0];
    NSString *str1 = [array objectAtIndex:1];
    NSString *str2 = [array objectAtIndex:2];
    NSString *str3 = [array objectAtIndex:3];
    NSString *str4 = [array objectAtIndex:4];
    if ([str4 hasPrefix:@"c2"]){
        // 电压
        NSString *dianya1 = [str0 substringFromIndex:5];
        NSString *dianya2 = [self string8resetWithStr:dianya1];
        NSString *dianya = [self HexToDWithHex:dianya2];
        self.dianya = [NSString stringWithFormat:@"%.1f", dianya.doubleValue / 100];
        // 电量
        CGFloat dianliang = 100 * (self.dianya.doubleValue - 32.5) / (41 - 32.5);
        int dian = (int)dianliang;
        if (dian > 100) {
            dian = 100;
        }
        if (dian < 0) {
            dian = 0;
        }
        self.dianliang = [NSString stringWithFormat:@"%d", dian];
        // 速度
        NSString *speed1 = [str1 substringToIndex:4];
        NSString *speed2 = [self string8resetWithStr:speed1];
        NSString *speed = [self HexToDWithHex:speed2];
        self.speed = [NSString stringWithFormat:@"%.1f", speed.doubleValue / 100];
        // 总里程
        NSString *lLu = [str2 substringToIndex:4];
        NSString *hLu = [str1 substringFromIndex:4];
        NSString *hlLu = [self string16resetWithHight:hLu low:lLu];
        NSString *allLu = [self HexToDWithHex:hlLu];
        self.allLu = [NSString stringWithFormat:@"%.2f", allLu.doubleValue / 1000];
        // 电流
        NSString *dianliu1 = [str2 substringFromIndex:4];
        NSString *dianliu2 = [self string8resetWithStr:dianliu1];
        NSString *dianliu = [self HexToDWithHex:dianliu2];
        self.dianliu = [NSString stringWithFormat:@"%.2f", dianliu.doubleValue / 100];
        // 温度
        NSString *temp1 = [str3 substringToIndex:4];
        NSString *temp2 = [self string8resetWithStr:temp1];
        NSString *temp = [self HexToDWithHex:temp2];
        self.temp = [NSString stringWithFormat:@"%.2f", temp.doubleValue / 100];
        // 骑行模式
        NSString *ride = [str3 substringWithRange:NSMakeRange(4, 2)];
        if ([ride isEqualToString:@"e0"]) {
            self.rideMode = @"高速模式";
        } else if ([ride isEqualToString:@"e1"]) {
            self.rideMode = @"中速模式";
        } else if ([ride isEqualToString:@"e2"]) {
            self.rideMode = @"低速模式";
        }
        // 充电模式
        NSString *charge = [str3 substringFromIndex:6];
        if ([charge isEqualToString:@"00"]) {
            self.rideMode = @"工作模式";
        } else if ([ride isEqualToString:@"0f"]) {
            self.rideMode = @"充电模式";
        }
    }
    if ([str4 hasPrefix:@"c5"]) {
        // 本次里程
        NSString *lLu = [str1 substringToIndex:4];
        NSString *hLu = [str0 substringFromIndex:5];
        NSString *hlLu = [self string16resetWithHight:hLu low:lLu];
        NSString *currentLu = [self HexToDWithHex:hlLu];
        self.currentLu = [NSString stringWithFormat:@"%.2f", currentLu.doubleValue / 1000];
        // 本次开机时间
        NSString *openTime1 = [str1 substringFromIndex:4];
        NSString *openTime2 = [self string8resetWithStr:openTime1];
        NSString *openTime = [self HexToDWithHex:openTime2];
        self.openTime = [NSString stringWithFormat:@"%d", openTime.intValue / 60];
        // 定时开机反馈时间
        NSString *setTime1 = [str2 substringToIndex:4];
        NSString *setTime2 = [self string8resetWithStr:setTime1];
        self.setTime = [self HexToDWithHex:setTime2];
        // 主板故障
        NSString *check1 = [str2 substringFromIndex:4];
        NSString *check = [self string8resetWithStr:check1];
        if ([check isEqualToString:@"0001"]) {
            self.check = @"左电机HALL故障";
        }  else if ([check isEqualToString:@"0002"]) {
            self.check = @"左电机电流检测( 运放坏)故障";
        } else if ([check isEqualToString:@"0004"]) {
            self.check = @"左电机电机线接错、短路等";
        } else if ([check isEqualToString:@"0008"]) {
            self.check = @"左电机电机过流";
        } else if ([check isEqualToString:@"0010"]) {
            self.check = @"左电机电机温度过高";
        } else if ([check isEqualToString:@"0020"]) {
            self.check = @"左电机速度过高（空转）";
        } else if ([check isEqualToString:@"0100"]) {
            self.check = @"右电机HALL故障";
        } else if ([check isEqualToString:@"0200"]) {
            self.check = @"右电机电流检测( 运放坏)故障";
        } else if ([check isEqualToString:@"0400"]) {
            self.check = @"右电机电机线接错、短路等";
        } else if ([check isEqualToString:@"0800"]) {
            self.check = @"右电机过流";
        } else if ([check isEqualToString:@"1000"]) {
            self.check = @"右电机温度过高故障";
        } else if ([check isEqualToString:@"2000"]) {
            self.check = @"右电机速度过高（空转）";
        } else if ([check isEqualToString:@"4000"]) {
            self.check = @"高电压电池故障";
        } else if ([check isEqualToString:@"8000"]) {
            self.check = @"低电压电池故障";
        }
        // 系统反馈报警速度
        NSString *alertSpeed1 = [str3 substringToIndex:2];
        self.alertSpeed = [self HexToDWithHex:alertSpeed1];
        // 反馈最高车速设置值
        NSString *maxSpeed1 = [str3 substringWithRange:NSMakeRange(2, 2)];
        self.maxSpeed = [self HexToDWithHex:maxSpeed1];
        // 反馈动力强度百分比
        NSString *strong1 = [str3 substringWithRange:NSMakeRange(4, 2)];
        self.strong = [self HexToDWithHex:strong1];
        // 反馈转向灵敏度百分比
        NSString *turn1 = [str3 substringFromIndex:6];
        self.turn = [self HexToDWithHex:turn1];
    }
}

#pragma mark - wirte
- (BOOL)setupTurn:(BOOL)turnon {
    if (!self.isConnectPeripheral) {
        [SVProgressHUD showInfoWithStatus:Language(@"请先连接设备")];
        return NO;
    }
    if (turnon) {
        // 开机
        [self bluetoothSetValue:@"00" forKey:@"3" type:CMDType85];
        return [self wirteData:CMDType85];
    } else {
        // 关机
        [self bluetoothSetValue:@"01" forKey:@"3" type:CMDType85];
        return [self wirteData:CMDType85];
    }
}
/** 修改名字 */
- (BOOL)setupName:(NSString *)name {
    if (!name.length) {
        return NO;
    }
    if (!self.isConnectPeripheral) {
        [SVProgressHUD showInfoWithStatus:Language(@"请先连接设备")];
        return NO;
    }
    if (!self.nameCharacteristic) {
        [SVProgressHUD showInfoWithStatus:Language(@"请连接本公司的设备进行设置")];
        return NO;
    }
    NSData *data = [name dataUsingEncoding:NSUTF8StringEncoding];
    [self.currentPeripheral writeValue:data forCharacteristic:self.nameCharacteristic type:CBCharacteristicWriteWithResponse];
    return YES;
}

/** 修改密码 */
- (BOOL)setupPassWord:(NSString *)name {
    if (!name.length) {
        return NO;
    }
    if (!self.isConnectPeripheral) {
        [SVProgressHUD showInfoWithStatus:Language(@"请先连接设备")];
        return NO;
    }
    if (!self.pwdCharacteristic) {
        [SVProgressHUD showInfoWithStatus:Language(@"请连接本公司的设备进行设置")];
        return NO;
    }
    NSData *data = [name dataUsingEncoding:NSUTF8StringEncoding];
    [self.currentPeripheral writeValue:data forCharacteristic:self.pwdCharacteristic type:CBCharacteristicWriteWithResponse];
    return YES;
}
/** 设置最大速度 */
- (BOOL)setupMaxSpeed:(int)value {
    if (!self.isConnectPeripheral) {
        [SVProgressHUD showInfoWithStatus:Language(@"请先连接设备")];
        return NO;
    }
    if (self.writeCharacteristic) {
        [self userSetValue:[NSString stringWithFormat:@"%d", value] forKey:MaxSpeed];
    }
    NSString *hexStr = [NSString stringWithFormat:@"%02x", value];
    [self bluetoothSetValue:hexStr forKey:@"0" type:CMDType86];
    return [self wirteData:CMDType86];
}
/** 设置动力强度 */
- (BOOL)setupStrong:(int)value {
    if (!self.isConnectPeripheral) {
        [SVProgressHUD showInfoWithStatus:Language(@"请先连接设备")];
        return NO;
    }
    if (self.writeCharacteristic) {
        [self userSetValue:[NSString stringWithFormat:@"%d", value] forKey:StrongSet];
    }
    NSString *hexStr = [NSString stringWithFormat:@"%02x", value];
    [self bluetoothSetValue:hexStr forKey:@"1" type:CMDType86];
    return [self wirteData:CMDType86];
}
/** 设置转向灵敏度 */
- (BOOL)setupTurnStrong:(int)value {
    if (!self.isConnectPeripheral) {
        [SVProgressHUD showInfoWithStatus:Language(@"请先连接设备")];
        return NO;
    }
    if (self.writeCharacteristic) {
        [self userSetValue:[NSString stringWithFormat:@"%d", value] forKey:TurnSet];
    }
    NSString *hexStr = [NSString stringWithFormat:@"%02x", value];
    [self bluetoothSetValue:hexStr forKey:@"2" type:CMDType86];
    return [self wirteData:CMDType86];
}
/** 定时关机 */
- (BOOL)setupTime:(int)value {
    if (!self.isConnectPeripheral) {
        [SVProgressHUD showInfoWithStatus:Language(@"请先连接设备")];
        return NO;
    }
    if (self.writeCharacteristic) {
        [self userSetValue:[NSString stringWithFormat:@"%d", value] forKey:TimeSet];
    }
    NSString *hexStr = [NSString stringWithFormat:@"%02x", value];
    [self bluetoothSetValue:hexStr forKey:@"4" type:CMDType86];
    return [self wirteData:CMDType86];
}

- (void)userSetValue:(NSString *)value forKey:(NSString *)key {
    NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
    [user setObject:value forKey:key];
}

- (NSString *)userGetValueForKey:(NSString *)key {
    NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
    return [user valueForKey:key];
}

- (BOOL)wirteData:(CMDType)type{
    if (!self.writeCharacteristic) {
        [SVProgressHUD showInfoWithStatus:Language(@"请连接本公司的设备进行设置")];
        return NO;
    }
    NSString *dataStr = nil;
    if (type == CMDType86) {
        dataStr = [self getBluetoothset:CMDType86];
    } else if (type == CMDType85) {
        dataStr = [self getBluetoothset:CMDType85];
    }
    NSString *hexStr = [NSString stringWithFormat:@"aa55%@14005a", dataStr];
    NSData *data = [self hexToBytes:hexStr];
    
    [self.currentPeripheral writeValue:data forCharacteristic:self.writeCharacteristic type:CBCharacteristicWriteWithoutResponse];
    return YES;
}

- (NSData *)hexToBytes:(NSString *)str {
    NSMutableData* data = [NSMutableData data];
    int idx;
    for (idx = 0; idx+2 <= str.length; idx+=2) {
        NSRange range = NSMakeRange(idx, 2);
        NSString* hexStr = [str substringWithRange:range];
        NSScanner* scanner = [NSScanner scannerWithString:hexStr];
        unsigned int intValue;
        [scanner scanHexInt:&intValue];
        [data appendBytes:&intValue length:1];
    }
    return data;
}


/** 16位高低位置换 */
- (NSString *)string16resetWithHight:(NSString *)hight low:(NSString *)low {
    NSString *low1 = [self string8resetWithStr:low];
    NSString *hight1 = [self string8resetWithStr:hight];
    return [hight1 stringByAppendingString:low1];
}

/** 8位高低位置换 */  // 0044
- (NSString *)string8resetWithStr:(NSString *)str {
    NSString *str1 = [str substringToIndex:2];
    NSString *str2 = [str substringFromIndex:2];
    NSString *newStr = [str2 stringByAppendingString:str1];
    return newStr;
}

/** 16进制转10进制 */
- (NSString *)HexToDWithHex:(NSString *)HexStr {
    return [NSString stringWithFormat:@"%lu",strtoul([HexStr UTF8String],0,16)];
}

- (NSString *)getBluetoothset:(CMDType)type {
    NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
    NSDictionary *dict;
    if (type == CMDType86) {
        dict = [user objectForKey:BluetoothSet86];
    } else if (type == CMDType85) {
        dict = [user objectForKey:BluetoothSet85];
    }
    NSMutableString *str = [[NSMutableString alloc] init];
    for (int i = 0; i < 15; i++) {
        NSString *value = dict[[NSString stringWithFormat:@"%d", i]];
        if (value.length) {
            [str appendString:value];
        }
    }
    return str;
}

- (void)bluetoothSetValue:(NSString *)value forKey:(NSString *)key type:(CMDType)type {
    NSUserDefaults *user = [NSUserDefaults standardUserDefaults];
    if (type == CMDType86) {
        NSDictionary *dict = [user objectForKey:BluetoothSet86];
        NSMutableDictionary *dict1 = [NSMutableDictionary dictionaryWithDictionary:dict];
        dict1[key] = value;
        [user setObject:dict1 forKey:BluetoothSet86];
        
    } else if (type == CMDType85){
        NSDictionary *dict = [user objectForKey:BluetoothSet85];
        NSMutableDictionary *dict1 = [NSMutableDictionary dictionaryWithDictionary:dict];
        dict1[key] = value;
        [user setObject:dict1 forKey:BluetoothSet85];
    }
}

#pragma mark - getter
- (NSMutableArray<CBPeripheral *> *)peripherals {
    if (!_peripherals) {
        _peripherals = [[NSMutableArray alloc] init];
    }
    return _peripherals;
}

- (NSMutableArray<NSUUID *> *)peripheralUUIDs {
    if (!_peripheralUUIDs) {
        _peripheralUUIDs = [[NSMutableArray alloc] init];
    }
    return _peripheralUUIDs;
}

- (NSString *)maxSpeed {
    if (_maxSpeed.intValue <= 6 || _maxSpeed.intValue > 18) {
        return [self userGetValueForKey:MaxSpeed];
    }
    return _maxSpeed;
}

- (NSString *)strong {
    if (_strong.intValue <= 50 || _strong.intValue > 100) {
        return [self userGetValueForKey:StrongSet];
    }
    return _strong;
}

- (NSString *)turn {
    if (_turn.intValue <= 50 || _turn.intValue > 100) {
        return [self userGetValueForKey:TurnSet];
    }
    return _turn;
}

- (NSString *)setTime {
    if ([_setTime isEqualToString:@"0"] || _setTime == nil) {
        return [self userGetValueForKey:TimeSet];
    }
    return _setTime;
}


@end
